import boto3
import xlsxwriter
from datetime import datetime, timezone, timedelta

# 设置未调用天数的阈值
days_without_invocation = 30


# 认证信息
class AwsAuthInfo:
    def __init__(self, aws_access_key_id, aws_secret_access_key, aws_region_name):
        self.aws_access_key_id = aws_access_key_id
        self.aws_secret_access_key = aws_secret_access_key
        self.aws_region_name = aws_region_name


# 各个区域的认证信息
aws_auth_map = {
    'prod-cn-north-1': AwsAuthInfo('AKIAYSJKU5UZSXIGG4DH', 'Hb86FDa/0frhdwpY95AYiKIOczIzB60q9eFlPLtg', 'cn-north-1'),
    'prod-us-east-2': AwsAuthInfo('AKIAVGNWUKMQCF2NKKNR', 'P/KVKrvnoFBHVQ4vlBqccPHlM0YLrTMr21KjCN6k', 'us-east-2'),
    "prod-eu-west-1": AwsAuthInfo('AKIAVGNWUKMQCF2NKKNR', 'P/KVKrvnoFBHVQ4vlBqccPHlM0YLrTMr21KjCN6k', 'eu-west-1'),
    "prod-us-east-1": AwsAuthInfo('AKIAVGNWUKMQCF2NKKNR', 'P/KVKrvnoFBHVQ4vlBqccPHlM0YLrTMr21KjCN6k', 'us-east-1'),
    "prod-us-west-2": AwsAuthInfo('AKIAVGNWUKMQCF2NKKNR', 'P/KVKrvnoFBHVQ4vlBqccPHlM0YLrTMr21KjCN6k', 'us-west-2'),
    "prod-eu-central-1": AwsAuthInfo('AKIAVGNWUKMQCF2NKKNR', 'P/KVKrvnoFBHVQ4vlBqccPHlM0YLrTMr21KjCN6k',
                                     'eu-central-1'),
    "qa-us-east-2": AwsAuthInfo('AKIASWZL2UIXKIZYED6A', '9Qh6EQAHGBDUIacQljUAdQb2bH8jT8Ov4CCdXJef', 'us-east-2'),
    'qa-eu-west-1': AwsAuthInfo('AKIASWZL2UIXKIZYED6A', '9Qh6EQAHGBDUIacQljUAdQb2bH8jT8Ov4CCdXJef', 'eu-west-1'),
    'qa-us-east-1': AwsAuthInfo('AKIASWZL2UIXKIZYED6A', '9Qh6EQAHGBDUIacQljUAdQb2bH8jT8Ov4CCdXJef', 'us-east-1')
}

# 创建一个新的 Excel 工作簿
workbook = xlsxwriter.Workbook('lambda_inactivity_report.xlsx')

# 创建下拉列表选择项
yes_no_options = ['是', '否']

# 设置单元格格式：居中
cell_format = workbook.add_format({'align': 'center', 'valign': 'vcenter'})


def get_no_invocation_lambda(region: str):
    aws_auth_info = aws_auth_map[region]
    worksheet = workbook.add_worksheet(aws_auth_info.aws_region_name)

    # 添加表头并加粗
    bold = workbook.add_format({'bold': True, 'align': 'center', 'valign': 'vcenter'})
    worksheet.write('A1', 'Function Name', bold)
    worksheet.write('B1', 'Handler', bold)
    worksheet.write('C1', 'Runtime', bold)
    worksheet.write('D1', 'Last Invocation', bold)
    worksheet.write('E1', '是否建议删除', bold)
    worksheet.write('F1', '作用', bold)
    worksheet.write('G1', '是否删除', bold)

    # 设置列宽和行高
    worksheet.set_column('A:A', 35)  # Function Name 列
    worksheet.set_column('B:B', 50)  # Handler 列
    worksheet.set_column('C:C', 15)  # Runtime 列
    worksheet.set_column('D:D', 25)  # Last Invocation 列
    worksheet.set_column('E:G', 15)  # E到G列
    worksheet.set_default_row(20)  # 设置默认行高

    # 初始化客户端
    lambda_client = boto3.client("lambda",
                                 aws_access_key_id=aws_auth_info.aws_access_key_id,
                                 aws_secret_access_key=aws_auth_info.aws_secret_access_key,
                                 region_name=aws_auth_info.aws_region_name)
    logs_client = boto3.client("logs",
                               aws_access_key_id=aws_auth_info.aws_access_key_id,
                               aws_secret_access_key=aws_auth_info.aws_secret_access_key,
                               region_name=aws_auth_info.aws_region_name)

    # 获取所有lambda函数的列表
    response = lambda_client.list_functions()
    functions = response['Functions']

    # 获取当前时间
    now = datetime.now(timezone.utc)
    row = 1  # 从第二行开始写入数据

    for function in functions:
        function_name = function['FunctionName']
        runtime = function['Runtime']
        handler = function['Handler']
        log_group_name = f'/aws/lambda/{function_name}'

        # 检查日志组是否存在
        try:
            log_group = logs_client.describe_log_groups(logGroupNamePrefix=log_group_name)

            if 'logGroups' in log_group and log_group['logGroups']:
                # 获取最新的日志流
                log_streams = logs_client.describe_log_streams(
                    logGroupName=log_group_name,
                    orderBy='LastEventTime',
                    descending=True,
                    limit=1
                )

                if log_streams['logStreams']:
                    last_event_time = log_streams['logStreams'][0]['lastEventTimestamp']
                    last_event_time = datetime.fromtimestamp(last_event_time / 1000, timezone.utc)

                    if now - last_event_time > timedelta(days=days_without_invocation):
                        worksheet.write(row, 0, function_name, cell_format)
                        worksheet.write(row, 1, handler, cell_format)
                        worksheet.write(row, 2, runtime, cell_format)
                        worksheet.write(row, 3, last_event_time.strftime('%Y-%m-%d %H:%M:%S'), cell_format)
                        worksheet.write(row, 4, '是', cell_format)
                        worksheet.data_validation(row, 4, row, 4, {'validate': 'list', 'source': yes_no_options})
                        worksheet.data_validation(row, 6, row, 6, {'validate': 'list', 'source': yes_no_options})
                        row += 1
                else:
                    worksheet.write(row, 0, function_name, cell_format)
                    worksheet.write(row, 1, handler, cell_format)
                    worksheet.write(row, 2, runtime, cell_format)
                    worksheet.write(row, 3, 'Never Invoked', cell_format)
                    worksheet.write(row, 4, '是', cell_format)
                    worksheet.data_validation(row, 4, row, 4, {'validate': 'list', 'source': yes_no_options})
                    worksheet.data_validation(row, 6, row, 6, {'validate': 'list', 'source': yes_no_options})
                    row += 1
            else:
                worksheet.write(row, 0, function_name, cell_format)
                worksheet.write(row, 1, handler, cell_format)
                worksheet.write(row, 2, runtime, cell_format)
                worksheet.write(row, 3, 'No Log Group', cell_format)
                worksheet.write(row, 4, '是', cell_format)
                worksheet.data_validation(row, 4, row, 4, {'validate': 'list', 'source': yes_no_options})
                worksheet.data_validation(row, 6, row, 6, {'validate': 'list', 'source': yes_no_options})
                row += 1

        except logs_client.exceptions.ResourceNotFoundException:
            worksheet.write(row, 0, function_name, cell_format)
            worksheet.write(row, 1, handler, cell_format)
            worksheet.write(row, 2, runtime, cell_format)
            worksheet.write(row, 3, 'No Log Group', cell_format)
            worksheet.write(row, 4, '是', cell_format)
            worksheet.data_validation(row, 4, row, 4, {'validate': 'list', 'source': yes_no_options})
            worksheet.data_validation(row, 6, row, 6, {'validate': 'list', 'source': yes_no_options})
            row += 1


if __name__ == '__main__':
    region_arr = (
        'prod-cn-north-1', 'prod-us-east-2', 'prod-eu-west-1', 'prod-us-east-1', 'prod-us-west-2', 'prod-eu-central-1')
    for region in region_arr:
        get_no_invocation_lambda(region)
    workbook.close()
